package com.eagle.videoboot.controller;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.UUID;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.eagle.videoboot.domain.entity.Bgm;
import com.eagle.videoboot.domain.entity.Comments;
import com.eagle.videoboot.domain.entity.Users;
import com.eagle.videoboot.domain.entity.Videos;
import com.eagle.videoboot.domain.vo.ResultVO;
import com.eagle.videoboot.enums.VideoStatusEnum;
import com.eagle.videoboot.service.IBgmService;
import com.eagle.videoboot.service.IUsersLikeVideosService;
import com.eagle.videoboot.service.IVideosService;
import com.eagle.videoboot.utils.FetchVideoCover;
import com.eagle.videoboot.utils.MergeVideoMp3;
import com.eagle.videoboot.utils.PagedResult;
import com.eagle.videoboot.utils.ResultVOUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.n3r.idworker.Sid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;


@RestController
@Api(value="视频相关业务的接口", tags= {"视频相关业务的controller"})
@RequestMapping("/video")
@Slf4j
public class VideoController {

	@Value("${file.avatar}")
	private String avatar;

	@Autowired
	private IBgmService bgmServiceImpl;
	
	@Autowired
	private IVideosService videosServiceImpl;

	@Autowired
	private IUsersLikeVideosService usersLikeVideosServiceImpl;

	@Autowired(required = false)
	private Sid sid;

	@GetMapping("/hello")
	public String hello(){
		return "Hello";
	}


	@ApiOperation(value="上传视频", notes="上传视频的接口")
	@ApiImplicitParams({
		@ApiImplicitParam(name="userId", value="用户id", required=true, 
				dataType="String", paramType="form"),
		@ApiImplicitParam(name="bgmId", value="背景音乐id", required=false, 
				dataType="String", paramType="form"),
		@ApiImplicitParam(name="videoSeconds", value="背景音乐播放长度", required=true, 
				dataType="String", paramType="form"),
		@ApiImplicitParam(name="videoWidth", value="视频宽度", required=true, 
				dataType="String", paramType="form"),
		@ApiImplicitParam(name="videoHeight", value="视频高度", required=true, 
				dataType="String", paramType="form"),
		@ApiImplicitParam(name="desc", value="视频描述", required=false, 
				dataType="String", paramType="form")
	})
	@PostMapping(value="/upload", headers="content-type=multipart/form-data")
	public ResultVO upload(String userId,
						   String bgmId, double videoSeconds,
						   int videoWidth, int videoHeight,
						   String desc,
						   @ApiParam(value="短视频", required=true)
				MultipartFile file) throws Exception {
		
		if (StringUtils.isBlank(userId)) {
			return ResultVOUtil.error("用户id不能为空...");
		}
		
		// 文件保存的命名空间
//		String fileSpace = "C:/imooc_videos_dev";
		// 保存到数据库中的相对路径
		String uploadPathDB = "/" + userId + "/video";
		String coverPathDB = "/" + userId + "/video";
		
		FileOutputStream fileOutputStream = null;
		InputStream inputStream = null;
		// 文件上传的最终保存路径
		String finalVideoPath = "";
		try {
			if (file != null) {
				
				String fileName = file.getOriginalFilename();
				log.info("upload image originalFilename {}",fileName);
				// abc.mp4
				String arrayFilenameItem[] =  fileName.split("\\.");
				String fileNamePrefix = "";
				for (int i = 0 ; i < arrayFilenameItem.length-1 ; i ++) {
					fileNamePrefix += arrayFilenameItem[i];
				}
				// fix bug: 解决小程序端OK，PC端不OK的bug，原因：PC端和小程序端对临时视频的命名不同
//				String fileNamePrefix = fileName.split("\\.")[0];
				
				if (StringUtils.isNotBlank(fileName)) {
					
					finalVideoPath = avatar + uploadPathDB + "/" + fileName;
					// 设置数据库保存的路径
					uploadPathDB += ("/" + fileName);
					coverPathDB = coverPathDB + "/" + fileNamePrefix + ".jpg";
					
					File outFile = new File(finalVideoPath);
					if (outFile.getParentFile() != null || !outFile.getParentFile().isDirectory()) {
						// 创建父文件夹
						outFile.getParentFile().mkdirs();
					}
					
					fileOutputStream = new FileOutputStream(outFile);
					inputStream = file.getInputStream();
					IOUtils.copy(inputStream, fileOutputStream);
				}
				
			} else {
				return ResultVOUtil.error("上传出错...");
			}
		} catch (Exception e) {
			e.printStackTrace();
			return ResultVOUtil.error("上传出错...");
		} finally {
			if (fileOutputStream != null) {
				fileOutputStream.flush();
				fileOutputStream.close();
			}
		}
		
		// 判断bgmId是否为空，如果不为空，
		// 那就查询bgm的信息，并且合并视频，生产新的视频
		if (StringUtils.isNotBlank(bgmId)) {
			QueryWrapper<Bgm> wrapper = new QueryWrapper<>();
			wrapper.eq("id",bgmId);
			Bgm bgm = bgmServiceImpl.getOne(wrapper);
			String mp3InputPath = avatar +"/backend-bgm"+ bgm.getPath();

			MergeVideoMp3 tool = new MergeVideoMp3();
			String videoInputPath = finalVideoPath;

			String videoOutputName = UUID.randomUUID().toString() + ".mp4";
			uploadPathDB = "/" + userId + "/video" + "/" + videoOutputName;
			finalVideoPath = avatar + uploadPathDB;
			tool.convert(videoInputPath, mp3InputPath, videoSeconds, finalVideoPath);
		}
		System.out.println("uploadPathDB=" + uploadPathDB);
		System.out.println("finalVideoPath=" + finalVideoPath);

//		// 对视频进行截图
		FetchVideoCover videoInfo = new FetchVideoCover();
		videoInfo.getCover(finalVideoPath, avatar + coverPathDB);
//
//		 保存视频信息到数据库
		Videos video = new Videos();
		String videoId = sid.nextShort();
		video.setId(videoId);
		video.setAudioId(bgmId);
		video.setUserId(userId);
		video.setVideoSeconds((float)videoSeconds);
		video.setVideoHeight(videoHeight);
		video.setVideoWidth(videoWidth);
		video.setVideoDesc(desc);
		video.setVideoPath(uploadPathDB);
		video.setCoverPath(coverPathDB);
		video.setStatus(VideoStatusEnum.SUCCESS.value);
		video.setCreateTime(LocalDateTime.now());

		videosServiceImpl.save(video);

		return ResultVOUtil.success(videoId);
	}
	
//	@ApiOperation(value="上传封面", notes="上传封面的接口")
//	@ApiImplicitParams({
//		@ApiImplicitParam(name="userId", value="用户id", required=true,
//				dataType="String", paramType="form"),
//		@ApiImplicitParam(name="videoId", value="视频主键id", required=true,
//				dataType="String", paramType="form")
//	})

//	@PostMapping(value="/uploadCover", headers="content-type=multipart/form-data")
//	public IMoocJSONResult uploadCover(String userId,
//				String videoId,
//				@ApiParam(value="视频封面", required=true)
//				MultipartFile file) throws Exception {
//
//		if (StringUtils.isBlank(videoId) || StringUtils.isBlank(userId)) {
//			return IMoocJSONResult.errorMsg("视频主键id和用户id不能为空...");
//		}
//
//		// 文件保存的命名空间
////		String fileSpace = "C:/imooc_videos_dev";
//		// 保存到数据库中的相对路径
//		String uploadPathDB = "/" + userId + "/video";
//
//		FileOutputStream fileOutputStream = null;
//		InputStream inputStream = null;
//		// 文件上传的最终保存路径
//		String finalCoverPath = "";
//		try {
//			if (file != null) {
//
//				String fileName = file.getOriginalFilename();
//				if (StringUtils.isNotBlank(fileName)) {
//
//					finalCoverPath = FILE_SPACE + uploadPathDB + "/" + fileName;
//					// 设置数据库保存的路径
//					uploadPathDB += ("/" + fileName);
//
//					File outFile = new File(finalCoverPath);
//					if (outFile.getParentFile() != null || !outFile.getParentFile().isDirectory()) {
//						// 创建父文件夹
//						outFile.getParentFile().mkdirs();
//					}
//
//					fileOutputStream = new FileOutputStream(outFile);
//					inputStream = file.getInputStream();
//					IOUtils.copy(inputStream, fileOutputStream);
//				}
//
//			} else {
//				return IMoocJSONResult.errorMsg("上传出错...");
//			}
//		} catch (Exception e) {
//			e.printStackTrace();
//			return IMoocJSONResult.errorMsg("上传出错...");
//		} finally {
//			if (fileOutputStream != null) {
//				fileOutputStream.flush();
//				fileOutputStream.close();
//			}
//		}
//
//		videoService.updateVideo(videoId, uploadPathDB);
//
//		return IMoocJSONResult.ok();
//	}

	/**
	 *
	 * @Description: 分页和搜索查询视频列表
	 * isSaveRecord：1 - 需要保存
	 * 				 0 - 不需要保存 ，或者为空的时候
	 */
	@PostMapping(value="/showAll")
	public ResultVO showAll(@RequestBody Videos video,
							Integer isSaveRecord,
							@RequestParam(required = false, defaultValue = "1") Integer page,
							@RequestParam(required = false, defaultValue = "10") Integer pageSize) throws Exception {


		PagedResult result = videosServiceImpl.getAllVideos(video, isSaveRecord, page, pageSize);
		return ResultVOUtil.success(result);
	}

	/**
	 * @Description: 我关注的人发的视频
	 */
	@PostMapping("/showMyFollow")
	public ResultVO showMyFollow(String userId,
								 @RequestParam(required = false, defaultValue = "1") Integer page,
								 @RequestParam(required = false, defaultValue = "6") Integer pageSize) throws Exception {

		if (StringUtils.isBlank(userId)) {
			return ResultVOUtil.success();
		}

		PagedResult videosList = videosServiceImpl.queryMyFollowVideos(userId, page, pageSize);

		return ResultVOUtil.success(videosList);
	}

	/**
	 * @Description: 我收藏(点赞)过的视频列表
	 */
	@PostMapping("/showMyLike")
	public ResultVO showMyLike(String userId,
							   @RequestParam(required = false, defaultValue = "1") Integer page,
							   @RequestParam(required = false, defaultValue = "6") Integer pageSize) throws Exception {

		if (StringUtils.isBlank(userId)) {
			return ResultVOUtil.success();
		}
		PagedResult videosList = videosServiceImpl.queryMyLikeVideos(userId, page, pageSize);

		return ResultVOUtil.success(videosList);
	}

	@PostMapping(value="/hot")
	public ResultVO hot() throws Exception {
		return ResultVOUtil.success(videosServiceImpl.getHotwords());
	}
//
	@PostMapping(value="/userLike")
	public ResultVO userLike(String userId, String videoId, String videoCreaterId)
			throws Exception {
		usersLikeVideosServiceImpl.userLikeVideo(userId, videoId, videoCreaterId);
		return ResultVOUtil.success();
	}

	@PostMapping(value="/userUnLike")
	public ResultVO userUnLike(String userId, String videoId, String videoCreaterId) throws Exception {
		usersLikeVideosServiceImpl.userUnLikeVideo(userId, videoId, videoCreaterId);
		return ResultVOUtil.success();
	}

	@PostMapping("/saveComment")
	public ResultVO saveComment(@RequestBody Comments comment,
			String fatherCommentId, String toUserId) throws Exception {

		comment.setFatherCommentId(fatherCommentId);
		comment.setToUserId(toUserId);

		videosServiceImpl.saveComment(comment);
		return ResultVOUtil.success();
	}

	@PostMapping("/getVideoComments")
	public ResultVO getVideoComments(String videoId, @RequestParam(required = false, defaultValue = "1") Integer page,
									 @RequestParam(required = false, defaultValue = "5") Integer pageSize) throws Exception {

		if (StringUtils.isBlank(videoId)) {
			return ResultVOUtil.success();
		}

		PagedResult list = videosServiceImpl.getAllComments(videoId, page, pageSize);

		return ResultVOUtil.success(list);
	}
	
}
